;; -*- scheme -*- Constants for network protocols
;; This file is part of scheme-GNUnet.
;; Copyright (C) 2001--2020 GNUnet e.V.
;; Copyright (C) 2021 Maxime Devos
;;
;; scheme-GNUnet is free software: you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the
;; Free Software Foundation, either version 3 of the License, or (at your
;; option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
;; for more details.
;;
;; You should have received a copy of the GNU General Public License along with
;; this program. If not, see <https://www.gnu.org/licenses/>.

(use-modules (srfi srfi-1))

(define (msg:filler begin end)
  (map (lambda (j)
	 `(value (symbol
		  ,(string->symbol
		    (string-append "msg:"(number->string (+ begin j)))))
		 (index ,(+ begin j))
		 (documentation "[Unassigned / undefined]")))
       (iota (- (+ 1 end) begin))))

;; TODO: proper docstrings.
(define entries
  `(;; Test if service is online.
    ;; @deprecated!
    msg:test ; 0
    ,@(include/sexp "enum-agpl.scmfrag")
    ,@(msg:filler 3 3)
    ,@(include/sexp "enum-resolver.scmfrag")
    ,@(include/sexp "enum-util.scmfrag")
    ,@(include/sexp "enum-arm.scmfrag")
    ,@(include/sexp "enum-hello.scmfrag")
    ,@(include/sexp "enum-fragment.scmfrag")
    ,@(msg:filler 20 38)
    ,@(include/sexp "enum-wlan.scmfrag")
    ,@(include/sexp "enum-transport-dv.scmfrag")
    ,@(msg:filler 54 54)
    ;; * Experimental message type
    msg:transport:xu ; 55
    ;; * Transport-UDP message types
    ;; Normal UDP message type.
    msg:transport:udp ; 56
    ;; UDP ACK.
    msg:transport:udp:ack ; 57
    ,@(msg:filler 58 59)
    ;; * Transport-TCP message types.
    ;; TCP NAT probe message, send from NAT'd peer to
    ;; other peer to establish bi-directional communication
    msg:transport:tcp:nat-probe ; 60
    msg:transport:tcp:welcome   ; 61
    ;; Message to force transport to update bandwith assignment
    ;; (LEGACY) FIXME I assume this means this isn't used anymore?
    msg:transport:ats ; 62
    ;; * NAT message types
    ;; Message to ask NAT server to perform traversal test
    msg:nat:test ; 63
    ,@(include/sexp "enum-core.scmfrag")
    ,@(msg:filler 90 91)
    ,@(include/sexp "enum-datastore.scmfrag")
    ,@(msg:filler 105 125)
    ,@(include/sexp "enum-fs.scmfrag")
    ,@(include/sexp "enum-dht.scmfrag")
    ,@(msg:filler 157 159)
    ;; * HOSTLIST message types
    ;; TODO comments
    msg:hostlist:advertisement ; 160
    ,@(msg:filler 161 167)
    ,@(include/sexp "enum-statistics.scmfrag")
    ,@(msg:filler 176 184)
    ,@(include/sexp "enum-vpn.scmfrag")
    ,@(msg:filler 205 210)
    ,@(include/sexp "enum-vpn-dns.scmfrag")
    ,@(msg:filler 215 299)
    ,@(include/sexp "enum-chat.scmfrag")
    ,@(msg:filler 312 320)
    ,@(include/sexp "enum-nse.scmfrag")
    ,@(msg:filler 324 329)
    ,@(include/sexp "enum-peerinfo.scmfrag")
    ,@(msg:filler 335 339)
    ,@(include/sexp "enum-ats.scmfrag")
    ,@(msg:filler 357 359)
    ,@(include/sexp "enum-transport.scmfrag")
    ,@(msg:filler 392 419)
    ,@(include/sexp "enum-fs-publish.scmfrag")
    ,@(msg:filler 427 430)
    ,@(include/sexp "enum-namecache.scmfrag")
    ,@(include/sexp "enum-namestore.scmfrag")
    ,@(include/sexp "enum-lockmanager.scmfrag")
    ,@(msg:filler 453 459)
    ,@(include/sexp "enum-testbed.scmfrag")
    ,@(msg:filler 497 499)
    ,@(include/sexp "enum-gns.scmfrag")
    ,@(msg:filler 505 519)
    ,@(include/sexp "enum-consensus.scmfrag")
    ,@(msg:filler 548 564)
    ,@(include/sexp "enum-set.scmfrag")
    ;; * TESTBED LOGGER message types
    ;; Message for TESTBED LOGGER
    msg:testbed-logger:msg ; 600
    ;; Message for TESTBED LOGGER acknowledgement
    msg:testbed-logger:ack ; 601
    ,@(msg:filler 602 619)
    ,@(include/sexp "enum-regex.scmfrag")
    ,@(msg:filler 623 623)
    ,@(include/sexp "enum-identity.scmfrag")
    ,@(msg:filler 634 635)
    ,@(include/sexp "enum-revocation.scmfrag")
    ,@(include/sexp "enum-scalarproduct.scmfrag")
    ,@(msg:filler 653 659)
    ,@(include/sexp "enum-psycstore.scmfrag")
    ,@(msg:filler 678 679)
    ,@(include/sexp "enum-psyc.scmfrag")
    ,@(msg:filler 706 729)
    ,@(include/sexp "enum-conversation.scmfrag")
    ,@(msg:filler 746 749)
    ,@(include/sexp "enum-multicast.scmfrag")
    ;; TODO:
    ;; SECRETSHARING,
    ;; PEERSTORE,
    ;; SOCIAL,
    ;; X-VINE DHT,
    ;; Whanau DHT,
    ;; RPS,
    ;; IDENTITY PROVIDER
    ;; ABD,
    ;; CADET,
    ;; AUCTION,
    ;; RPS DEBUG,
    ;; NEW (TNG) Transport
    ))


(define (fix-entry entry index)
  (cond ((symbol? entry)
	 `(value (symbol ,entry)
		 (index ,index)))
	(else entry)))

(define entries/fixed
  (map fix-entry entries (iota (length entries))))

;; Makes sure indices are correct
(define (verify-entry e index)
  (cond ((pair? e)
	 (unless (= (car (assq-ref (cdr e) 'index)) index)
	   (error "incorrect index ~a for ~a" index e)))
	(else 'presumably-ok)))

(for-each verify-entry
	  entries/fixed
	  (iota (length entries/fixed)))

(define result
  `(define-library (gnu gnunet message protocols)
     (export message-type message-type?)
     (import (rnrs base)
     	     (rnrs enums)
	     (gnu extractor enum))
     (begin
       ;; TODO when to include an ! and when not.
       ;; TODO cross-referenes
       ;;
       ;; Maybe some future version
       ;; of guile could have special support
       ;; for enumerations, such that enumeration
       ;; symbol names have their own special section
       ;; (benefit: can be swapped or stripped out when unused)
       ;; and numeric enumeration values are inlined
       ;; in depending modules?

       ;; Enumeration of known message types.
       ;; Experimental or non-standard services
       ;; may need to use raw integers instead.
       (define-enumeration (message-type message-type?)
	 (#:documentation "Types of messages used in GNUnet")
	 (#:max 65535)
	 (#:known ,@entries/fixed)))))
